﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Components;
using Components.Enum;
using Model;
using MsDAL;
using ServiceHelper.Util;

namespace ServiceHelper.Doc
{
    public abstract class DocumentManager
    {
        private Sto8a00 _doc;
        protected Sto8a00 Doc
        {
            get { return _doc; }
            set { _doc = value; }
        }

        public abstract Sto8a00 CreateDefaultModel();

        public void ProcessDoc()
        {
            string usercode = ServerContext.UserCode;

            if (Doc.Docdate == null)
                Doc.Docdate = DateTime.Now;

            if (string.IsNullOrEmpty(Doc.Docno))
                CreateDocno();

            if (string.IsNullOrEmpty(Doc.Listid))
                Doc.Listid = Sys0a60Manager.Entity.CreateSn("sto8a00_listid", usercode);

            if (!string.IsNullOrEmpty(Doc.Changecode))
                CheckChangeCode(Doc.Listid, Doc.Changecode);

            //赋新的changecodwe
            Doc.Changecode = Guid.NewGuid().ToString();

            if (Doc.Docstatus == null)
                Doc.Docstatus = DocumentStatus.Normal;

            if (Doc.Audstatus == null)
                Doc.Audstatus = AuditStatus.NoRequirement;

            if (string.IsNullOrEmpty(Doc.Usercode))
                Doc.Usercode = ServerContext.GetComDesc;

            double totalAmout = 0;
            double totalQty = 0;
            foreach (var row in Doc.Rows)
            {
                if (string.IsNullOrEmpty(row.Dtlid))
                    row.Dtlid = Sys0a60Manager.Entity.CreateSn("sto8a01_listid", usercode);

                row.Dtldoctype = Doc.Doctype;
                row.Dtlwarehouseid = Doc.Warehouseid;
                row.Dtldocid = Doc.Listid;

                if (row.Startbuyqty <= 0 && row.Dtlprice <= 0) //界面未对商品的价格和起订量赋值，按商品成本价计算
                {
                    var pot3A00 = Pot3a00Manager.Entity.GetModelById(row.Merchid);
                    if (pot3A00 != null)
                    {
                        row.Startbuyqty = pot3A00.Bordqty;
                        row.Dtlprice = pot3A00.Pamt; //成本价
                    }
                }

                if (Doc.Doctype == DocumentType.Adjust)
                    row.Dtlstockqty = row.Dtlqty;

                else if (Doc.Doctype == DocumentType.PurchaseReturn)
                    row.Dtlstockqty = row.Dtlqty;

                var amt = row.Dtlqty * row.Dtlprice;

                row.Dtltotalamt = amt;

                totalAmout += row.Dtltotalamt;
                totalQty += row.Dtlqty;
            }

            Doc.Totalamt = totalAmout;
            Doc.Totalqty = totalQty;
        }

        private void CheckChangeCode(string docId, string changeNum)
        {
            var oldChangeNum = Sto8a00Manager.Entity.GetValueByField(docId, "changecode");
            if (Validation.ToString(oldChangeNum) != changeNum)
            {
                throw new StnException("此单据已经被他人修改，请重新操作");
            }
        }

        public virtual string Save()
        {
            using (var tran = new TransactionScope())
            {
                ProcessDoc();

                var sqlList = new List<SqlApp>();

                if (Doc.Status == ModelStatus.Add)
                    sqlList.Add(Sto8a00Manager.Entity.Add(Doc));
                else if (Doc.Status == ModelStatus.Changed)
                    sqlList.Add(Sto8a00Manager.Entity.Update(Doc));
                else if (Doc.Status == ModelStatus.Delete)
                    sqlList.Add(Sto8a00Manager.Entity.Delete(Doc));

                foreach (var row in Doc.Rows)
                {
                    if (row.Status == ModelStatus.Add)
                        sqlList.Add(Sto8a01Manager.Entity.Add(row));
                    else if (row.Status == ModelStatus.Changed)
                        sqlList.Add(Sto8a01Manager.Entity.Update(row));
                    else if (row.Status == ModelStatus.Delete)
                        sqlList.Add(Sto8a01Manager.Entity.Delete(row));
                }

                if (Doc.Rows.Count == 0)
                    return "没有数据被保存!";

                string msg = CommonManager.Entity.SaveData(sqlList);
                if (!string.IsNullOrEmpty(msg))
                    throw new StnException(msg);
                else
                    AfterSubmit();

                tran.Complete();
            }

            return null;
        }

        protected virtual void AfterSubmit()
        {

        }

        protected virtual void CreateDocno(Sto8a00 doc = null)
        {
            using (var tran = new TransactionScope())
            {
                if (doc == null)
                    doc = Doc;

                var codeName = string.Format("{0}_docno", doc.Doctype);

                doc.Docno = Sys0a60Manager.Entity.CreateSn(codeName, ServerContext.UserCode);

                tran.Complete();
            }
        }

        public virtual void Parse(Sto8a00 sto8a00)
        {
            this.Doc = sto8a00;
        }
    }
}
